home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / asm_mmx.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  5KB  |  190 lines

  1. /* $Id: asm_mmx.c,v 1.1 1998/03/27 04:40:07 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: asm_mmx.c,v $
  26.  * Revision 1.1  1998/03/27 04:40:07  brianp
  27.  * Initial revision
  28.  *
  29.  */
  30.  
  31.  
  32. #ifdef MMX
  33.  
  34.  
  35. void gl_mmx_blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
  36.                                 GLubyte rgba[][4], const GLubyte dest[][4] )
  37. {
  38.  
  39.   long long SUBMASK  =0x00ff000000ff0000LL;
  40.   long long HIGHMASK =0xFFFFFFFF00000000LL;
  41.   long long LOWMASK  =0x00000000FFFFFFFFLL;
  42.   
  43.    GLuint i;
  44.  
  45.    ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
  46.    ASSERT(ctx->Color.BlendSrc==GL_SRC_ALPHA);
  47.    ASSERT(ctx->Color.BlendDst==GL_ONE_MINUS_SRC_ALPHA);
  48.  
  49.    if(((unsigned long)rgba&4 + (unsigned long)dest&4 ) == 8) {
  50.      GLint t = rgba[0][ACOMP];  /* t in [0,255] */
  51.      GLint s = 255 - t;
  52.      GLint r = (rgba[0][RCOMP] * t + dest[0][RCOMP] * s) >> 8;
  53.      GLint g = (rgba[0][GCOMP] * t + dest[0][GCOMP] * s) >> 8;
  54.      GLint b = (rgba[0][BCOMP] * t + dest[0][BCOMP] * s) >> 8;
  55.      GLint a = (rgba[0][ACOMP] * t + dest[0][ACOMP] * s) >> 8;
  56.      rgba[0][RCOMP] = r;
  57.      rgba[0][GCOMP] = g;
  58.      rgba[0][BCOMP] = b;
  59.      rgba[0][ACOMP] = a;
  60.  
  61.      mask++;
  62.      rgba++;
  63.      dest++;
  64.      n--;
  65.      /*puts("odd adress!");*/
  66.    }
  67.    
  68.    if(n) {
  69.      for (i=0;i<n/2;i++) {
  70.        if (mask[i*2]) {
  71.  
  72.      __asm__ (
  73.           "movq (%0), %%mm4\n\t"  /* mm4 = rgba[i] rgba[i+1]*/
  74.           "pxor %%mm5,%%mm5\n\t"
  75.  
  76.           "movq %%mm4, %%mm1\n\t"
  77.  
  78.           "movq (%1), %%mm7\n\t"  /* mm7 = dest[i] dest[i+1] */
  79.  
  80.           "punpcklbw %%mm5, %%mm1\n\t" /* mm1 = rgba[i] */
  81.  
  82.           "movq %%mm7, %%mm6\n\t"          
  83.           
  84.           "movq %%mm1, %%mm0\n\t"
  85.  
  86.           "punpcklbw %%mm5, %%mm6\n\t" /* mm6 = dest[i] */
  87.  
  88.           "movq %%mm1, %%mm2\n\t"      /* mm2 = rgba[i]  */
  89.  
  90.           "psrlq  $48, %%mm0\n\t"        /* mm0 = mm0 & 0xFF  */
  91.           
  92.           "punpckhbw %%mm5, %%mm4\n\t" /* mm4 = rgba[i+1] */
  93.  
  94.           "packssdw  %%mm0, %%mm0\n\t" /* mm0 = 0 t 0 t  */
  95.           
  96.           "movq %%mm0, %%mm3\n\t"          
  97.  
  98.           "punpckhbw %%mm5, %%mm7\n\t" /* mm7 = dest[i+1] */
  99.  
  100.           "psllq $16, %%mm3\n\t"        /* mm3 = t 0 t 0  */
  101.  
  102.           "por %3, %%mm0\n\t"        /* mm0 = 255 t 255 t  */      
  103.  
  104.           "punpcklwd %%mm6, %%mm1\n\t" /* mm1 = rgba[i][RCOMP] dest[i][RCOMP] rgba[i][GCOMP] dest[i][GCOMP] */
  105.  
  106.           "psubw %%mm3, %%mm0\n\t"     /* mm0 = s[i]           t[i]           s[i]           t[i]*/
  107.           
  108.           "punpckhwd %%mm6, %%mm2\n\t" /* mm2 = rgba[i][BCOMP] dest[i][BCOMP] rgba[i][ACOMP] dest[i][ACOMP] */
  109.  
  110.           "movq %%mm4, %%mm3\n\t"
  111.                               
  112.           "psrlq  $48, %%mm3\n\t"        /* mm3 = mm3 >> 48 */
  113.  
  114.           "packssdw  %%mm3, %%mm3\n\t" /* mm3 = 0 t 0 t */
  115.           
  116.           "movq %%mm3, %%mm6\n\t"
  117.           
  118.           "por %3, %%mm3\n\t"        /* mm3 = 255 t 255 t */
  119.           
  120.           "psllq $16, %%mm6\n\t"        /* mm3 = t  0  t   0 */
  121.           
  122.           "psubw %%mm6, %%mm3\n\t"     /* mm3 = s[i+1]           t[i+1]           s[i+1]           t[i+1] */
  123.           
  124.           "movq %%mm4, %%mm5\n\t"      /* mm5 = rgba[i+1] */
  125.  
  126.           "punpcklwd %%mm7, %%mm4\n\t" /* mm4 = rgba[i+1][RCOMP] dest[i+1][RCOMP] rgba[i+1][GCOMP] dest[i+1][GCOMP] */
  127.           "punpckhwd %%mm7, %%mm5\n\t" /* mm5 = rgba[i+1][BCOMP] dest[i+1][BCOMP] rgba[i+1][ACOMP] dest[i+1][ACOMP] */
  128.           
  129.           "pmaddwd %%mm0, %%mm1\n\t"
  130.  
  131.           "pmaddwd %%mm3, %%mm4\n\t"
  132.  
  133.           "pmaddwd %%mm0, %%mm2\n\t"
  134.  
  135.           "pmaddwd %%mm3, %%mm5\n\t"
  136.           
  137.           "psrld $8, %%mm1\n\t"
  138.           "psrld $8, %%mm2\n\t"
  139.  
  140.           "psrld $8, %%mm4\n\t"
  141.           "packssdw %%mm2, %%mm1\n\t"  /* mm2 = rgba[i] */
  142.  
  143.           "psrld $8, %%mm5\n\t"          
  144.           "packuswb %%mm1, %%mm1\n\t"
  145.  
  146.           "packssdw %%mm5, %%mm4\n\t"  /* mm5 = rgba[i+1] */
  147.           "pand %4, %%mm1\n\t"          
  148.           
  149.           "packuswb %%mm4, %%mm4\n\t" 
  150.           "pand %2, %%mm4\n\t"
  151.           
  152.           "por %%mm1, %%mm4\n\t"  /* mm2 = rgba[i] rgba[i+1] */
  153.           "movq %%mm4, (%0)\n\t"
  154.           
  155.           : /* no output */
  156.           : "r" (rgba[i*2]),  "r" (dest[i*2]), "m" (HIGHMASK), "m" (SUBMASK), "m" (LOWMASK)
  157.           : "memory" );
  158.      
  159.        }
  160.      }
  161.      __asm__("emms":::"memory");  
  162.    }
  163.  
  164.    if(n&1) {
  165.      GLint t = rgba[n-1][ACOMP];  /* t in [0,255] */
  166.      GLint s = 255 - t;
  167.      GLint r = (rgba[n-1][RCOMP] * t + dest[n-1][RCOMP] * s) >> 8;
  168.      GLint g = (rgba[n-1][GCOMP] * t + dest[n-1][GCOMP] * s) >> 8;
  169.      GLint b = (rgba[n-1][BCOMP] * t + dest[n-1][BCOMP] * s) >> 8;
  170.      GLint a = (rgba[n-1][ACOMP] * t + dest[n-1][ACOMP] * s) >> 8;
  171.      rgba[n-1][RCOMP] = r;
  172.      rgba[n-1][GCOMP] = g;
  173.      rgba[n-1][BCOMP] = b;
  174.      rgba[n-1][ACOMP] = a;
  175.  
  176.      /*puts("odd n!");*/
  177.    }
  178. }
  179.  
  180.  
  181. #else
  182.  
  183.  
  184. /* some compilers don't accept sources files without code */
  185. void gl_mmx_dummy_function(void)
  186. {
  187. }
  188.  
  189. #endif
  190.